package com.gitee.zw.irmp.common.config;

import com.gitee.zw.irmp.common.auth.sso.IrmpTokenRetriever;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Set;

import static com.gitee.zw.irmp.common.auth.sso.SSOProcessor.AUTH_COOKIE_NAME;

@Slf4j
public class ClientHttpHeaderInterceptor implements ClientHttpRequestInterceptor {
    static final Set<String> EXCLUDE_HEADERS = Set.of("content-type", "accept", "content-length", "host", "connection", "user-agent");
    IrmpTokenRetriever tokenRetriever;

    public ClientHttpHeaderInterceptor(IrmpTokenRetriever tokenRetriever) {
        this.tokenRetriever = tokenRetriever;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        if (requestAttributes != null) {
            //老请求
            HttpServletRequest request0 = requestAttributes.getRequest();
            Enumeration<String> headerNames = request0.getHeaderNames();
            if (headerNames.hasMoreElements()) {
                headerNames.asIterator().forEachRemaining(name -> {
                    if (EXCLUDE_HEADERS.contains(name.toLowerCase(Locale.ROOT))) {
                        log.trace("ignored header: {}", name);
                    } else {
                        request.getHeaders().add(name, request0.getHeader(name));
                        log.trace("Header: {} = {}", name, request0.getHeader(name));
                    }
                });
            } else {
                setDefaultToken(request);
            }
        } else {
            log.warn("No Request attributes found.");
            setDefaultToken(request);
        }
        return execution.execute(request, body);
    }

    private void setDefaultToken(HttpRequest request) {
        if (tokenRetriever != null) {
            String token = tokenRetriever.getToken();
            log.debug("Default Token: {}", token);
            if (token != null) {
                request.getHeaders().add(AUTH_COOKIE_NAME, "Bearer " + token);
            }
        }
    }

}
